﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.DB;
using YArchitech.LIB;
using HYCoordinate;
using HYRevitCode.ElementSearchUtility.LinkDocumentSuite;
using YJKRGeometry;

namespace HYOpeningDetail
{
	internal class DimensionElementsInfo
	{
		public void GetDimensionElements(Autodesk.Revit.DB.Document doc, ViewPlan viewPlan, ref DimElementData dimElementData, List<double> lstLevelValue)
		{
			this.m_lstLevelValue = lstLevelValue;
			this.GetAllBox(doc, viewPlan, ref dimElementData);
			this.GetAllGap(doc, viewPlan, ref dimElementData);
			this.GetPipe(doc, viewPlan, ref dimElementData);
			this.GetCableTray(doc, viewPlan, ref dimElementData);
			this.GetDuct(doc, viewPlan, ref dimElementData);
			this.GetEquipBasement(doc, viewPlan, ref dimElementData.m_dicEquipBaseBox, "水箱");
			this.GetEquipBasement(doc, viewPlan, ref dimElementData.m_dicEquipBasePumb, "泵");
			if (OpeningViewDataSetForm.BChkBeamDimTop)
			{
				this.GetAllLinerElement(doc, viewPlan, BuiltInCategory.OST_Floors, ref dimElementData.m_lstFloorAndBeam);
				this.GetAllLinerElement(doc, viewPlan, BuiltInCategory.OST_StructuralFraming, ref dimElementData.m_lstFloorAndBeam);
			}
		}

		private void GetAllBox(Autodesk.Revit.DB.Document doc, ViewPlan viewPlan, ref DimElementData dimElementData)
		{
			this.GetAllElementByFamilyName(doc, viewPlan, ref dimElementData.m_dicEquip, BuiltInCategory.OST_MechanicalEquipment, PublicData.strArrMachineryEqument, 0);
			this.GetAllElementByFamilyName(doc, viewPlan, ref dimElementData.m_dicEquip, BuiltInCategory.OST_ElectricalEquipment, PublicData.strArrElectricalEqument, 1);
			this.GetAllElementByFamilyName(doc, viewPlan, ref dimElementData.m_dicEquip, BuiltInCategory.OST_FireAlarmDevices, PublicData.strArrFireEqument, 2);
			this.GetAllElementByFamilyName(doc, viewPlan, ref dimElementData.m_dicEquip, BuiltInCategory.OST_CommunicationDevices, PublicData.strArrCommunicateEqument, 3);
			this.GetAllElementByFamilyName(doc, viewPlan, ref dimElementData.m_dicEquip, BuiltInCategory.OST_MechanicalEquipment, new string[]
			{
				"分集水器"
			}, 4);
			this.GetAllElementByFamilyName(doc, viewPlan, ref dimElementData.m_dicEquip, BuiltInCategory.OST_DuctTerminal, new string[]
			{
				"风口",
				"散流器"
			}, 5);
		}

		private void GetAllGap(Autodesk.Revit.DB.Document doc, ViewPlan viewPlan, ref DimElementData dimElementData)
		{
			this.GetAllElementByFamilyName(doc, viewPlan, ref dimElementData.m_dicGap, BuiltInCategory.OST_IOSModelGroups, null, 0);
			this.GetAllElementByFamilyName(doc, viewPlan, ref dimElementData.m_dicGap, BuiltInCategory.OST_PipeAccessory, new string[]
			{
				"地漏"
			}, 3);
			this.GetAllElementByFamilyName(doc, viewPlan, ref dimElementData.m_dicGap, BuiltInCategory.OST_SpecialityEquipment, new string[]
			{
				"集水坑"
			}, 4);
			this.GetAllElementByFamilyName(doc, viewPlan, ref dimElementData.m_dicGap, BuiltInCategory.OST_DetailComponents, new string[]
			{
				"套管"
			}, 5);
		}

		private void GetPipe(Autodesk.Revit.DB.Document doc, ViewPlan viewPlan, ref DimElementData dimElementData)
		{
			this.GetAllLinerElement(doc, viewPlan, BuiltInCategory.OST_PipeCurves, ref dimElementData.m_lstPipe);
		}

		private void GetCableTray(Autodesk.Revit.DB.Document doc, ViewPlan viewPlan, ref DimElementData dimElementData)
		{
			this.GetAllLinerElement(doc, viewPlan, BuiltInCategory.OST_CableTray, ref dimElementData.m_lstCableTray);
		}

		private void GetDuct(Autodesk.Revit.DB.Document doc, ViewPlan viewPlan, ref DimElementData dimElementData)
		{
			this.GetAllLinerElement(doc, viewPlan, BuiltInCategory.OST_DuctCurves, ref dimElementData.m_lstDuct);
		}

		private void GetEquipBasement(Autodesk.Revit.DB.Document doc, ViewPlan viewPlan, ref Dictionary<FamilyInstance, ElementInfo> dicEquipBasement, string strFamilyName)
		{
			List<FamilyInstance> list = new List<FamilyInstance>();
			this.GetEquipBasementByName(doc, viewPlan, BuiltInCategory.OST_MechanicalEquipment, ref list, strFamilyName);
			foreach (FamilyInstance familyInstance in list)
			{
				BoundingBoxXYZ boundingBoxXYZ = familyInstance.get_BoundingBox(viewPlan);
				BoundingBoxIntersectsFilter filter = new BoundingBoxIntersectsFilter(new Outline(boundingBoxXYZ.Min.Subtract(new XYZ(0.0, 0.0, NumbericTools.mmToFeet(100.0))), boundingBoxXYZ.Max));
				FilteredElementCollectorLinkDocument filteredElementCollectorLinkDocument = new FilteredElementCollectorLinkDocument(doc);
				filteredElementCollectorLinkDocument.OfCategory(BuiltInCategory.OST_SpecialityEquipment).WherePass(filter).WhereElementIsNotElementType();
				List<BaseLinkDocumentResultBean> list2 = filteredElementCollectorLinkDocument.ToBeans();
				new List<Element>();
				foreach (BaseLinkDocumentResultBean baseLinkDocumentResultBean in list2)
				{
					FamilyInstance familyInstance2 = baseLinkDocumentResultBean.UseElement as FamilyInstance;
					if (familyInstance2 != null)
					{
						RevitLinkInstance useLinkeInstance = baseLinkDocumentResultBean.UseLinkeInstance;
						ElementInfo elementInfo = new ElementInfo();
						if (familyInstance2.Symbol.Family.Name.Contains("基础") || familyInstance2.Symbol.Family.Name.Contains("减震"))
						{
							elementInfo.element = familyInstance2;
							elementInfo.revitLink = useLinkeInstance;
							dicEquipBasement.Add(familyInstance, elementInfo);
						}
					}
				}
			}
		}

		private bool GetAllElementByFamilyName(Autodesk.Revit.DB.Document doc, ViewPlan viewPlan, ref Dictionary<ElementInfo, int> dicElement, BuiltInCategory builtInCategory, string[] arFamilyName, int i)
		{
			BoundingBoxIntersectsFilter boundingBoxIntersectsFilter = null;
			PublicFunction.GetViewBox(viewPlan, this.m_lstLevelValue, ref boundingBoxIntersectsFilter, true);
			Outline boundingBox = boundingBoxIntersectsFilter.GetBoundingBox();
			FilteredElementCollectorLinkDocument filteredElementCollectorLinkDocument = new FilteredElementCollectorLinkDocument(doc);
			try
			{
				List<BaseLinkDocumentResultBean> list2;
				if (arFamilyName == null || arFamilyName.Contains("套管"))
				{
					List<BaseLinkDocumentResultBean> list = new List<BaseLinkDocumentResultBean>();
					if (arFamilyName == null)
					{
						list2 = filteredElementCollectorLinkDocument.OfCategory(builtInCategory).OfCalss(typeof(Group)).WhereElementIsNotElementType().ToBeans();
					}
					else
					{
						list2 = filteredElementCollectorLinkDocument.OfCategory(builtInCategory).WhereElementIsNotElementType().ToBeans();
					}
					if (list2.Count < 0)
					{
						return false;
					}
					foreach (BaseLinkDocumentResultBean baseLinkDocumentResultBean in list2)
					{
						if (baseLinkDocumentResultBean.UseLinkeInstance == null)
						{
							XYZ groupBoundingBoxMax = this.GetGroupBoundingBoxMax(baseLinkDocumentResultBean.UseElement);
							if (groupBoundingBoxMax != null && Geometry.LessThan(groupBoundingBoxMax.Z, boundingBox.MaximumPoint.Z) && Geometry.Greaterthan_Or_Equal(groupBoundingBoxMax.Z, boundingBox.MinimumPoint.Z))
							{
								list.Add(baseLinkDocumentResultBean);
							}
						}
						else
						{
							Transform transform = baseLinkDocumentResultBean.UseLinkeInstance.GetTransform();
							XYZ xyz = this.GetGroupBoundingBoxMax(baseLinkDocumentResultBean.UseElement);
							if (xyz != null)
							{
								xyz = transform.OfPoint(xyz);
								if (Geometry.LessThan(xyz.Z, boundingBox.MaximumPoint.Z) && Geometry.Greaterthan_Or_Equal(xyz.Z, boundingBox.MinimumPoint.Z))
								{
									list.Add(baseLinkDocumentResultBean);
								}
							}
						}
					}
					list2 = list;
				}
				else
				{
					filteredElementCollectorLinkDocument.AddViewLimit(boundingBoxIntersectsFilter);
					list2 = filteredElementCollectorLinkDocument.OfCategory(builtInCategory).WhereElementIsNotElementType().ToBeans();
				}
				foreach (BaseLinkDocumentResultBean baseLinkDocumentResultBean2 in list2)
				{
					RevitLinkInstance useLinkeInstance = baseLinkDocumentResultBean2.UseLinkeInstance;
					Element useElement = baseLinkDocumentResultBean2.UseElement;
					ElementInfo elementInfo = new ElementInfo();
					elementInfo.element = useElement;
					elementInfo.revitLink = useLinkeInstance;
					if (useElement is Group)
					{
						dicElement.Add(elementInfo, i);
					}
					else
					{
						FamilyInstance familyInstance = useElement as FamilyInstance;
						if (familyInstance != null)
						{
							if (arFamilyName == null)
							{
								dicElement.Add(elementInfo, i);
							}
							else
							{
								foreach (string value in arFamilyName)
								{
									if (familyInstance.Symbol.Family.Name.Contains(value))
									{
										if (dicElement != null && dicElement.Count < 1)
										{
											dicElement.Add(elementInfo, i);
										}
										if (!dicElement.ContainsKey(elementInfo))
										{
											dicElement.Add(elementInfo, i);
										}
									}
								}
							}
						}
					}
				}
			}
			catch (Exception)
			{
				return false;
			}
			return true;
		}

		private void GetAllLinerElement(Autodesk.Revit.DB.Document doc, ViewPlan viewPlan, BuiltInCategory builtInCategory, ref List<ElementInfo> lstElemInfo)
		{
			BoundingBoxIntersectsFilter input = null;
			PublicFunction.GetViewBox(viewPlan, this.m_lstLevelValue, ref input, true);
			FilteredElementCollectorLinkDocument filteredElementCollectorLinkDocument = new FilteredElementCollectorLinkDocument(doc);
			filteredElementCollectorLinkDocument.AddViewLimit(input);
			foreach (BaseLinkDocumentResultBean baseLinkDocumentResultBean in filteredElementCollectorLinkDocument.OfCategory(builtInCategory).WhereElementIsNotElementType().ToBeans())
			{
				Element useElement = baseLinkDocumentResultBean.UseElement;
				RevitLinkInstance useLinkeInstance = baseLinkDocumentResultBean.UseLinkeInstance;
				ElementInfo elementInfo = new ElementInfo();
				if (useElement != null)
				{
					elementInfo.element = useElement;
					elementInfo.revitLink = useLinkeInstance;
					lstElemInfo.Add(elementInfo);
				}
			}
		}

		private void GetEquipBasementByName(Autodesk.Revit.DB.Document doc, ViewPlan viewPlan, BuiltInCategory builtInCategory, ref List<FamilyInstance> lstFamilyInstance, string strFamilyName)
		{
			BoundingBoxIntersectsFilter input = null;
			PublicFunction.GetViewBox(viewPlan, this.m_lstLevelValue, ref input, true);
			FilteredElementCollectorLinkDocument filteredElementCollectorLinkDocument = new FilteredElementCollectorLinkDocument(doc);
			filteredElementCollectorLinkDocument.AddViewLimit(input);
			foreach (BaseLinkDocumentResultBean baseLinkDocumentResultBean in filteredElementCollectorLinkDocument.OfCategory(builtInCategory).WhereElementIsNotElementType().ToBeans())
			{
				FamilyInstance familyInstance = baseLinkDocumentResultBean.UseElement as FamilyInstance;
				if (familyInstance != null && familyInstance.Symbol.Family.Name.Contains(strFamilyName))
				{
					lstFamilyInstance.Add(familyInstance);
				}
			}
		}

		private XYZ GetGroupBoundingBoxMax(Element elem)
		{
			XYZ result = null;
			if (elem is Group)
			{
				Group drainGroup = elem as Group;
				DrainBuryDataStruct drainBuryDataStruct = new DrainBuryDataStruct();
				DrainBuryData.ReadDataFromDrain("43FEE925-0EBE-45D8-BA6F-72A4411E065A", drainGroup, "DrainBuryData", out drainBuryDataStruct);
				DataSerializeDeserialize.StringToPoint(drainBuryDataStruct.m_strMaxPoint, out result);
			}
			else
			{
				result = ((elem as FamilyInstance).Location as LocationPoint).Point;
			}
			return result;
		}

		private List<double> m_lstLevelValue;
	}
}
